Fix clipping issue with clip masks
authorAlexander Larsson <alexl@redhat.com>
Tue, 25 Aug 2009 08:16:39 +0000 (10:16 +0200)
committerAlexander Larsson <alexl@redhat.com>
Tue, 25 Aug 2009 08:37:18 +0000 (10:37 +0200)
When the clip mask is completely inside the drawable clip region we
don't change the clip at all. However, we did set region_tag_applied,
so when the drawable clip was removed we removed the original clip mask.
This is no good, so we fix that by returning early in this case.

Fixes issue reported in bug #592752.

gdk/gdkgc.c

index 699cebfc2420516c7d22524eb8954f6cd87a2fb1..13d9c8dab1db74238902bbc806915f7c323cdecc 100644 (file)
@@ -648,7 +648,7 @@ _gdk_gc_add_drawable_clip (GdkGC     *gc,
       GdkColor black = {0, 0, 0, 0};
       GdkRectangle r;
       GdkOverlapType overlap;
-      
+
       gdk_drawable_get_size (priv->clip_mask, &w, &h);
 
       r.x = 0;
@@ -659,7 +659,7 @@ _gdk_gc_add_drawable_clip (GdkGC     *gc,
       /* Its quite common to expose areas that are completely in or outside
        * the region, so we try to avoid allocating bitmaps that are just fully
        * set or completely unset.
-       */ 
+       */
       overlap = gdk_region_rect_in (region, &r);
       if (overlap == GDK_OVERLAP_RECTANGLE_PART)
        {
@@ -683,11 +683,19 @@ _gdk_gc_add_drawable_clip (GdkGC     *gc,
        }
       else if (overlap == GDK_OVERLAP_RECTANGLE_OUT)
        {
+         /* No intersection, set empty clip region */
          GdkRegion *empty = gdk_region_new ();
 
+         gdk_region_destroy (region);
          priv->old_clip_mask = g_object_ref (priv->clip_mask);
+         priv->clip_region = empty;
          _gdk_windowing_gc_set_clip_region (gc, empty, FALSE);
-         gdk_region_destroy (empty);
+       }
+      else
+       {
+         /* Completely inside region, don't set unnecessary clip */
+         gdk_region_destroy (region);
+         return;
        }
     }
   else
@@ -696,7 +704,7 @@ _gdk_gc_add_drawable_clip (GdkGC     *gc,
       priv->clip_region = region;
       if (priv->old_clip_region)
        gdk_region_intersect (region, priv->old_clip_region);
-      
+
       _gdk_windowing_gc_set_clip_region (gc, priv->clip_region, FALSE);
     }
 
@@ -718,6 +726,12 @@ _gdk_gc_remove_drawable_clip (GdkGC *gc)
          gdk_gc_set_clip_mask (gc, priv->old_clip_mask);
          g_object_unref (priv->old_clip_mask);
          priv->old_clip_mask = NULL;
+
+         if (priv->clip_region)
+           {
+             g_object_unref (priv->clip_region);
+             priv->clip_region = NULL;
+           }
        }
       else
        {